package ThreadDemo2;

/**
 * @Author Zhang Chao
 * @Date 2021/6/1 19:42
 * @Version 1.0
 */

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * 仓库栈
 */
public class MyStack {

    //栈使用数组来进行存储
    // 属性
    // 存储数组
    private Goods[] goodsStack;

    // 栈顶指针
    private int index;
    // 仓库栈的容量【数组的长度】
    private int stackCount;

    // Lock接口锁的使用
    private Lock lock; // 等价于 synchronized 关键字的用法

    // 获取枷锁条件对象
    private Condition condition;  // 等价于 Object类的 wait-notify 机制


    public MyStack(int stackCount , Lock lock , Condition condition){
        this.stackCount = stackCount;
        if(this.stackCount<=0){
            this.stackCount = 10;
        }

        goodsStack = new Goods[this.stackCount];
        index = 0;

        this.lock = lock;
        this.condition= condition;
    }

    public void push(Goods goods){
        lock.lock();
        try {
            if(index>=stackCount){
                // 进入阻塞队列
                condition.await();
            }
            goodsStack[index] = goods;
            index++;
            System.out.println("生产者生产了一个商品...."+index);
            condition.signalAll();// 等价于 Object类的 notifyAll
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            lock.unlock();
        }
    }

    public Goods pop(){
        Goods goods = null;
        lock.lock();
        try {
            if(index<=0){
                condition.await();// 等价于Object类的 wait方法 进入 挂起 状态
            }
            index--; //当前位置   应为看入栈操作 index 指向的最后一个位置的下一个
            // 取出当前位置的商品
            goods = goodsStack[index];
            // 将当前栈顶位置置空
            goodsStack[index] = null;
            System.out.println("消费者消费了一个商品。。。");
            condition.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return goods;

    }

}
